package com.xbongbong.paas.outerlink;

import com.xbongbong.outLink.domain.entity.OuterLinkEntity;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.model.OuterLinkModel;
import com.xbongbong.paas.outerlink.interfaces.PaasOuterLinkService;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.pro.enums.errorcodes.OutLinkErrorCodeEnum;
import com.xbongbong.saas.enums.OuterLinkTypeEnum;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;


/**
 * 外链接口登记处类
 * @author zheng.li
 */
@Component
public class OuterLinkRegistry implements ApplicationContextAware {

    private Map<String, PaasOuterLinkService> paasOuterLinkServiceBeanMap;

    private Map<Integer, PaasOuterLinkService> paasOuterLinkServiceMap;

    @Resource
    private OuterLinkModel outerLinkModel;

    /**
     * 默认的外链接口
     */
    private PaasOuterLinkService defaultOuterLinkService;



    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        // 获取PaasOuterLinkService 类型的所有bean
        paasOuterLinkServiceBeanMap = applicationContext.getBeansOfType(PaasOuterLinkService.class);
    }

    /**
     * 将bean map转换为业务类型为key的映射
     * @return Map<Integer, PaasOuterLinkService>
     */
    @Bean("paasOuterLinkServiceMap")
    public Map<Integer, PaasOuterLinkService> businessDetailMap() {
        paasOuterLinkServiceMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        this.paasOuterLinkServiceBeanMap.forEach((key, item)->{
            item.businessType().forEach(businessType->{
                paasOuterLinkServiceMap.put(Integer.valueOf(businessType.toString()), item);
            });
            if (item.businessType().contains(0)) {
                defaultOuterLinkService = item;
            }
        });
        return paasOuterLinkServiceMap;
    }

    /**
     * 获取实际处理类
     * @param businessType 业务类型
     * @return PaasOuterLinkService
     * @throws XbbException  系统异常
     */
    public PaasOuterLinkService getExecutor(Integer businessType) throws XbbException {
        PaasOuterLinkService paasOuterLinkService = paasOuterLinkServiceMap.get(businessType);
        paasOuterLinkService = paasOuterLinkService != null ?  paasOuterLinkService : defaultOuterLinkService;
        if (paasOuterLinkService == null) {
            throw new XbbException(-1,"该业务未支持外链");
        }
        return paasOuterLinkService;
    }

    /**
     * 获取实际处理类
     * @param token token
     * @return PaasOuterLinkService
     * @throws XbbException  系统异常
     */
    public PaasOuterLinkService getExecutor(String token) throws XbbException {
        OuterLinkEntity outerLinkEntity = getByToken(token,OuterLinkTypeEnum.WRITE.getCode());
        PaasOuterLinkService paasOuterLinkService = paasOuterLinkServiceMap.get(outerLinkEntity.getBusinessType());
        paasOuterLinkService = paasOuterLinkService != null ?  paasOuterLinkService : defaultOuterLinkService;
        if (paasOuterLinkService == null) {
            throw new XbbException(-1,"该业务未支持外链");
        }
        return paasOuterLinkService;
    }


    /**
     * 根据token 获取外链设置数据
     * @param token token
     * @return OuterLinkEntity
     * @throws XbbException 系统异常
     */
    public OuterLinkEntity getByToken(String token,Integer type) throws XbbException {
        Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        params.put("hashCode", token);
        params.put("del", 0);
        List<OuterLinkEntity> outerLinkEntityList = outerLinkModel.findEntitys(params);
        if (CollectionsUtil.isEmpty(outerLinkEntityList)){
            throw new XbbException(OutLinkErrorCodeEnum.API_ERROR_405006);
        }
//        // 外链填写有拓展链接 外面关闭 里面的链接也应失效
        if (Objects.equals(type,OuterLinkTypeEnum.WRITE.getCode())) {
            for (int i = 0; i < outerLinkEntityList.size(); i++) {
                OuterLinkEntity outerLinkEntity = outerLinkEntityList.get(i);
                if (Objects.nonNull(outerLinkEntity.getAttr()) || Objects.nonNull(outerLinkEntity.getExpandField())) {
                    Integer businessType = outerLinkEntity.getBusinessType();
                    Long formId = outerLinkEntity.getFormId();
                    String corpid = outerLinkEntity.getCorpid();
                    params.clear();
                    params.put("businessType", businessType);
                    params.put("del", 0);
                    params.put("formId", formId);
                    params.put("corpid", corpid);
                    params.put("type", OuterLinkTypeEnum.WRITE.getCode());
                    params.put("excludeExpandField", "excludeExpandField");
                    List<OuterLinkEntity> outerLinkEntityLists = outerLinkModel.findEntitys(params);
                    if (Objects.nonNull(outerLinkEntityLists)) {
                        if (Objects.equals(outerLinkEntityLists.get(0).getEnable(), 0)) {
                            throw new XbbException(OutLinkErrorCodeEnum.API_ERROR_405010);
                        }
                    }
                    return outerLinkEntity;
                }
            }
        }
        if (Objects.equals(outerLinkEntityList.get(0).getEnable(),0)){
            throw new XbbException(OutLinkErrorCodeEnum.API_ERROR_405010);
        }
        return outerLinkEntityList.get(0);
    }


}
